Sync xdgmime to the copy in gio
authorMatthias Clasen <matthiasc@src.gnome.org>
Wed, 16 Apr 2008 22:18:27 +0000 (22:18 +0000)
committerMatthias Clasen <matthiasc@src.gnome.org>
Wed, 16 Apr 2008 22:18:27 +0000 (22:18 +0000)
svn path=/trunk/; revision=20013

gtk/xdgmime/ChangeLog
gtk/xdgmime/xdgmime.c
gtk/xdgmime/xdgmime.h
gtk/xdgmime/xdgmimecache.c
gtk/xdgmime/xdgmimecache.h
gtk/xdgmime/xdgmimemagic.c
gtk/xdgmime/xdgmimemagic.h

index bd59c940c9210b1b0bd2c84ee6bc31a172ad494b..f72f9f857352108b9c633435aec555d8f2213a91 100644 (file)
@@ -1,3 +1,7 @@
+2008-04-16  Matthias Clasen  <mclasen@redhat.com>
+
+       * Sync xdgmime to the copy in gio.
+
 2008-04-16  Matthias Clasen  <mclasen@redhat.com>
 
        Partically revert the last commit after realizing that
index 7ca7d6e431823b69cc5be2359b96212f9c62c144..332c16537edc5ee43f7f88150158a9c59d743cbf 100644 (file)
@@ -93,17 +93,26 @@ struct XdgCallbackList
 typedef int (*XdgDirectoryFunc) (const char *directory,
                                 void       *user_data);
 
-static XdgDirTimeList *
-xdg_dir_time_list_new (void)
+static void
+xdg_dir_time_list_add (char   *file_name, 
+                      time_t  mtime)
 {
-  XdgDirTimeList *retval;
-
-  retval = calloc (1, sizeof (XdgDirTimeList));
-  retval->checked = XDG_CHECKED_UNCHECKED;
+  XdgDirTimeList *list;
 
-  return retval;
+  for (list = dir_time_list; list; list = list->next) 
+    {
+      if (strcmp (list->directory_name, file_name) == 0) 
+        return;
+    }
+  
+  list = calloc (1, sizeof (XdgDirTimeList));
+  list->checked = XDG_CHECKED_UNCHECKED;
+  list->directory_name = file_name;
+  list->mtime = mtime;
+  list->next = dir_time_list;
+  dir_time_list = list;
 }
-
 static void
 xdg_dir_time_list_free (XdgDirTimeList *list)
 {
@@ -123,7 +132,6 @@ xdg_mime_init_from_directory (const char *directory)
 {
   char *file_name;
   struct stat st;
-  XdgDirTimeList *list;
 
   assert (directory != NULL);
 
@@ -135,11 +143,7 @@ xdg_mime_init_from_directory (const char *directory)
 
       if (cache != NULL)
        {
-         list = xdg_dir_time_list_new ();
-         list->directory_name = file_name;
-         list->mtime = st.st_mtime;
-         list->next = dir_time_list;
-         dir_time_list = list;
+         xdg_dir_time_list_add (file_name, st.st_mtime);
 
          _caches = realloc (_caches, sizeof (XdgMimeCache *) * (n_caches + 2));
          _caches[n_caches] = cache;
@@ -156,12 +160,7 @@ xdg_mime_init_from_directory (const char *directory)
   if (stat (file_name, &st) == 0)
     {
       _xdg_mime_glob_read_from_file (global_hash, file_name);
-
-      list = xdg_dir_time_list_new ();
-      list->directory_name = file_name;
-      list->mtime = st.st_mtime;
-      list->next = dir_time_list;
-      dir_time_list = list;
+      xdg_dir_time_list_add (file_name, st.st_mtime);
     }
   else
     {
@@ -173,12 +172,7 @@ xdg_mime_init_from_directory (const char *directory)
   if (stat (file_name, &st) == 0)
     {
       _xdg_mime_magic_read_from_file (global_magic, file_name);
-
-      list = xdg_dir_time_list_new ();
-      list->directory_name = file_name;
-      list->mtime = st.st_mtime;
-      list->next = dir_time_list;
-      dir_time_list = list;
+      xdg_dir_time_list_add (file_name, st.st_mtime);
     }
   else
     {
@@ -296,12 +290,11 @@ xdg_check_file (const char *file_path,
 
       for (list = dir_time_list; list; list = list->next)
        {
-         if (! strcmp (list->directory_name, file_path) &&
-             st.st_mtime == list->mtime)
+         if (! strcmp (list->directory_name, file_path))
            {
-             if (list->checked == XDG_CHECKED_UNCHECKED)
+             if (st.st_mtime == list->mtime)
                list->checked = XDG_CHECKED_VALID;
-             else if (list->checked == XDG_CHECKED_VALID)
+             else 
                list->checked = XDG_CHECKED_INVALID;
 
              return (list->checked != XDG_CHECKED_VALID);
@@ -440,16 +433,17 @@ xdg_mime_init (void)
 
 const char *
 xdg_mime_get_mime_type_for_data (const void *data,
-                                size_t      len)
+                                size_t      len,
+                                int        *result_prio)
 {
   const char *mime_type;
 
   xdg_mime_init ();
 
   if (_caches)
-    return _xdg_mime_cache_get_mime_type_for_data (data, len);
+    return _xdg_mime_cache_get_mime_type_for_data (data, len, result_prio);
 
-  mime_type = _xdg_mime_magic_lookup_data (global_magic, data, len, NULL, 0);
+  mime_type = _xdg_mime_magic_lookup_data (global_magic, data, len, result_prio, NULL, 0);
 
   if (mime_type)
     return mime_type;
@@ -524,7 +518,7 @@ xdg_mime_get_mime_type_for_file (const char  *file_name,
       return XDG_MIME_TYPE_UNKNOWN;
     }
 
-  mime_type = _xdg_mime_magic_lookup_data (global_magic, data, bytes_read,
+  mime_type = _xdg_mime_magic_lookup_data (global_magic, data, bytes_read, NULL,
                                           mime_types, n);
 
   free (data);
@@ -552,6 +546,19 @@ xdg_mime_get_mime_type_from_file_name (const char *file_name)
     return XDG_MIME_TYPE_UNKNOWN;
 }
 
+int
+xdg_mime_get_mime_types_from_file_name (const char *file_name,
+                                       const char  *mime_types[],
+                                       int          n_mime_types)
+{
+  xdg_mime_init ();
+  
+  if (_caches)
+    return _xdg_mime_cache_get_mime_types_from_file_name (file_name, mime_types, n_mime_types);
+  
+  return _xdg_glob_hash_lookup_file_name (global_hash, file_name, mime_types, n_mime_types);
+}
+
 int
 xdg_mime_is_valid_mime_type (const char *mime_type)
 {
index a4b0997293c5d75130cc27fef31fc87be11b53cf..fde7cfe1638f1b768291ec443f334449bf29a722 100644 (file)
@@ -50,13 +50,17 @@ typedef void (*XdgMimeDestroy)  (void *user_data);
 #define xdg_mime_get_mime_type_for_data       XDG_ENTRY(get_mime_type_for_data)
 #define xdg_mime_get_mime_type_for_file       XDG_ENTRY(get_mime_type_for_file)
 #define xdg_mime_get_mime_type_from_file_name XDG_ENTRY(get_mime_type_from_file_name)
+#define xdg_mime_get_mime_types_from_file_name XDG_ENTRY(get_mime_types_from_file_name)
 #define xdg_mime_is_valid_mime_type           XDG_ENTRY(is_valid_mime_type)
 #define xdg_mime_mime_type_equal              XDG_ENTRY(mime_type_equal)
+#define _xdg_mime_mime_type_equal             XDG_ENTRY(mime_type_equal_p)
 #define xdg_mime_media_type_equal             XDG_ENTRY(media_type_equal)
 #define xdg_mime_mime_type_subclass           XDG_ENTRY(mime_type_subclass)
+#define _xdg_mime_mime_type_subclass          XDG_ENTRY(mime_type_subclass_p)
 #define xdg_mime_get_mime_parents             XDG_ENTRY(get_mime_parents)
 #define xdg_mime_list_mime_parents            XDG_ENTRY(list_mime_parents)
 #define xdg_mime_unalias_mime_type            XDG_ENTRY(unalias_mime_type)
+#define _xdg_mime_unalias_mime_type           XDG_ENTRY(unalias_mime_type_p)  
 #define xdg_mime_get_max_buffer_extents       XDG_ENTRY(get_max_buffer_extents)
 #define xdg_mime_shutdown                     XDG_ENTRY(shutdown)
 #define xdg_mime_dump                         XDG_ENTRY(dump)
@@ -69,10 +73,14 @@ extern const char xdg_mime_type_unknown[];
 #define XDG_MIME_TYPE_UNKNOWN xdg_mime_type_unknown
 
 const char  *xdg_mime_get_mime_type_for_data       (const void *data,
-                                                   size_t      len);
+                                                   size_t      len,
+                                                   int        *result_prio);
 const char  *xdg_mime_get_mime_type_for_file       (const char *file_name,
                                                     struct stat *statbuf);
 const char  *xdg_mime_get_mime_type_from_file_name (const char *file_name);
+int          xdg_mime_get_mime_types_from_file_name(const char *file_name,
+                                                   const char *mime_types[],
+                                                   int         n_mime_types);
 int          xdg_mime_is_valid_mime_type           (const char *mime_type);
 int          xdg_mime_mime_type_equal              (const char *mime_a,
                                                    const char *mime_b);
@@ -101,6 +109,7 @@ int          _xdg_mime_mime_type_equal             (const char *mime_a,
                                                    const char *mime_b);
 int          _xdg_mime_mime_type_subclass          (const char *mime,
                                                    const char *base);
+const char  *_xdg_mime_unalias_mime_type           (const char *mime);
 
 
 #ifdef __cplusplus
index 8717214fad27b4011132a28c13627f519378b879..8e762a175afb7a835503006ca19b1b6e4f4ec13f 100644 (file)
@@ -623,6 +623,7 @@ _xdg_mime_cache_get_max_buffer_extents (void)
 static const char *
 cache_get_mime_type_for_data (const void *data,
                              size_t      len,
+                             int        *result_prio,
                              const char *mime_types[],
                              int         n_mime_types)
 {
@@ -647,11 +648,15 @@ cache_get_mime_type_for_data (const void *data,
        }
     }
 
+  if (result_prio)
+    *result_prio = priority;
+  
   if (priority > 0)
     return mime_type;
 
   for (n = 0; n < n_mime_types; n++)
     {
+      
       if (mime_types[n])
        return mime_types[n];
     }
@@ -661,9 +666,10 @@ cache_get_mime_type_for_data (const void *data,
 
 const char *
 _xdg_mime_cache_get_mime_type_for_data (const void *data,
-                                       size_t      len)
+                                       size_t      len,
+                                       int        *result_prio)
 {
-  return cache_get_mime_type_for_data (data, len, NULL, 0);
+  return cache_get_mime_type_for_data (data, len, result_prio, NULL, 0);
 }
 
 const char *
@@ -726,7 +732,7 @@ _xdg_mime_cache_get_mime_type_for_file (const char  *file_name,
       return XDG_MIME_TYPE_UNKNOWN;
     }
 
-  mime_type = cache_get_mime_type_for_data (data, bytes_read,
+  mime_type = cache_get_mime_type_for_data (data, bytes_read, NULL,
                                            mime_types, n);
 
   free (data);
@@ -746,6 +752,14 @@ _xdg_mime_cache_get_mime_type_from_file_name (const char *file_name)
     return XDG_MIME_TYPE_UNKNOWN;
 }
 
+int
+_xdg_mime_cache_get_mime_types_from_file_name (const char *file_name,
+                                              const char  *mime_types[],
+                                              int          n_mime_types)
+{
+  return cache_glob_lookup_file_name (file_name, mime_types, n_mime_types);
+}
+
 #if 1
 static int
 is_super_type (const char *mime)
@@ -851,7 +865,7 @@ _xdg_mime_cache_unalias_mime_type (const char *mime)
 char **
 _xdg_mime_cache_list_mime_parents (const char *mime)
 {
-  int i, j, k, p;
+  int i, j, k, l, p;
   char *all_parents[128]; /* we'll stop at 128 */ 
   char **result;
 
@@ -878,14 +892,25 @@ _xdg_mime_cache_list_mime_parents (const char *mime)
              for (k = 0; k < n_parents && p < 127; k++)
                {
                  parent_mime_offset = GET_UINT32 (cache->buffer, parents_offset + 4 + 4 * k);
-                 all_parents[p++] = cache->buffer + parent_mime_offset;
+
+                 /* Don't add same parent multiple times.
+                  * This can happen for instance if the same type is listed in multiple directories
+                  */
+                 for (l = 0; l < p; l++)
+                   {
+                     if (strcmp (all_parents[l], cache->buffer + parent_mime_offset) == 0)
+                       break;
+                   }
+
+                 if (l == p)
+                   all_parents[p++] = cache->buffer + parent_mime_offset;
                }
 
              break;
            }
        }
     }
-  all_parents[p++] = 0;
+  all_parents[p++] = NULL;
   
   result = (char **) malloc (p * sizeof (char *));
   memcpy (result, all_parents, p * sizeof (char *));
index 39d506e147be412b7a044f9888e893b4414f9554..1cd978faecf1d207341b941db074045d28de782f 100644 (file)
@@ -39,6 +39,7 @@ typedef struct _XdgMimeCache XdgMimeCache;
 #define _xdg_mime_cache_get_mime_type_for_data        XDG_ENTRY(cache_get_mime_type_for_data)
 #define _xdg_mime_cache_get_mime_type_for_file        XDG_ENTRY(cache_get_mime_type_for_file)
 #define _xdg_mime_cache_get_mime_type_from_file_name  XDG_ENTRY(cache_get_mime_type_from_file_name)
+#define _xdg_mime_cache_get_mime_types_from_file_name XDG_ENTRY(cache_get_mime_types_from_file_name)
 #define _xdg_mime_cache_list_mime_parents             XDG_ENTRY(cache_list_mime_parents)
 #define _xdg_mime_cache_mime_type_subclass            XDG_ENTRY(cache_mime_type_subclass)
 #define _xdg_mime_cache_unalias_mime_type             XDG_ENTRY(cache_unalias_mime_type)
@@ -53,9 +54,13 @@ void          _xdg_mime_cache_unref         (XdgMimeCache *cache);
 
 
 const char  *_xdg_mime_cache_get_mime_type_for_data       (const void *data,
-                                                          size_t      len);
+                                                          size_t      len,
+                                                          int        *result_prio);
 const char  *_xdg_mime_cache_get_mime_type_for_file       (const char  *file_name,
                                                           struct stat *statbuf);
+int          _xdg_mime_cache_get_mime_types_from_file_name (const char *file_name,
+                                                           const char  *mime_types[],
+                                                           int          n_mime_types);
 const char  *_xdg_mime_cache_get_mime_type_from_file_name (const char *file_name);
 int          _xdg_mime_cache_is_valid_mime_type           (const char *mime_type);
 int          _xdg_mime_cache_mime_type_equal              (const char *mime_a,
index 6088edb276b052cd65568e2bb43c5cdb941b5ad3..a2320f584916c20b258565f3d5072da5f6553485 100644 (file)
@@ -656,21 +656,24 @@ const char *
 _xdg_mime_magic_lookup_data (XdgMimeMagic *mime_magic,
                             const void   *data,
                             size_t        len,
+                            int           *result_prio,
                              const char   *mime_types[],
                              int           n_mime_types)
 {
   XdgMimeMagicMatch *match;
   const char *mime_type;
   int n;
+  int prio;
 
+  prio = 0;
   mime_type = NULL;
   for (match = mime_magic->match_list; match; match = match->next)
     {
       if (_xdg_mime_magic_match_compare_to_data (match, data, len))
        {
-         if ((mime_type == NULL) || (_xdg_mime_mime_type_subclass (match->mime_type, mime_type))) {
-           mime_type = match->mime_type;
-         }
+         prio = match->priority;
+         mime_type = match->mime_type;
+         break;
        }
       else 
        {
@@ -691,6 +694,9 @@ _xdg_mime_magic_lookup_data (XdgMimeMagic *mime_magic,
            mime_type = mime_types[n];
        }
     }
+  
+  if (result_prio)
+    *result_prio = prio;
 
   return mime_type;
 }
index 16578962b52d7c4c2ffd211993f20067935a07ca..8f113051e02fa85b194dda48b3f80bb327a1c206 100644 (file)
@@ -50,6 +50,7 @@ int           _xdg_mime_magic_get_buffer_extents (XdgMimeMagic *mime_magic);
 const char   *_xdg_mime_magic_lookup_data        (XdgMimeMagic *mime_magic,
                                                  const void   *data,
                                                  size_t        len,
+                                                 int          *result_prio,
                                                  const char   *mime_types[],
                                                  int           n_mime_types);